﻿using System;
using System.Reflection;

namespace ebc.componentbinder
{
    internal class InputPin
    {
        private const string EVENTHANDLER_PREFIX1 = "Process";
        private const string EVENTHANDLER_PREFIX2 = "Handle";

        private readonly object component;
        private readonly MethodInfo methodInfo;


        public InputPin(object component, MethodInfo methodInfo)
        {
            this.component = component;
            this.methodInfo = methodInfo;
        }


        public Type ComponentType
        {
            get
            {
                return this.component.GetType();
            }
        }


        public Type ParameterType
        {
            get
            {
                return methodInfo.GetParameters()[0].ParameterType;
            }
        }


        public string PinName
        {
            get
            {
                if (methodInfo.Name.StartsWith(EVENTHANDLER_PREFIX1, StringComparison.InvariantCultureIgnoreCase))
                    return methodInfo.Name.Substring(EVENTHANDLER_PREFIX1.Length);
                if (methodInfo.Name.StartsWith(EVENTHANDLER_PREFIX2, StringComparison.InvariantCultureIgnoreCase))
                    return methodInfo.Name.Substring(EVENTHANDLER_PREFIX2.Length);
                return "";
            }
        }


        public Delegate CreateDelegate()
        {
            return Delegate.CreateDelegate(typeof(Action<>).MakeGenericType(this.ParameterType), this.component, this.methodInfo, false);
        }


        public override bool Equals(System.Object obj)
        {
            if (obj == null) return false;

            InputPin ip = obj as InputPin;
            if (ip == null) return false;

            return this.component == ip.component &&
                   this.ParameterType == ip.ParameterType &&
                   this.PinName == ip.PinName;
        }


        public override string ToString()
        {
            return string.Format("In: {0}.[Process]{1}({2})", this.ComponentType.FullName, this.PinName, this.ParameterType.FullName);
        }
    }
}
